﻿using LiveCharts;
using Ping9719.WpfEx;
using Ping9719.WpfEx.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Input;

namespace BaseUi.ViewModel
{
    public class HomeViewModel : BindableBase
    {
        CancellationTokenSource cancellationToken = null;//停止
        ManualResetEvent manualReset = null;//暂停、继续
        WarnInfoContainer WarnInfo = new WarnInfoContainer();//警告、错误等信息

        #region 绑定
        private string textErr;
        /// <summary>
        /// 错误文本
        /// </summary>
        public string TextErr { get => textErr; set { SetProperty(ref textErr, value); } }
        public ICommand ClearTextInfoCommand { get => new DelegateCommand(ClearTextInfo); }
        /// <summary>
        /// 清除信息文本
        /// </summary>
        public void ClearTextInfo()
        {
            TextBoxLog.ClearLog();
        }
        public ICommand ClearTextErrCommand { get => new DelegateCommand(ClearTextErr); }
        /// <summary>
        /// 清除全部错误文本
        /// </summary>
        public void ClearTextErr()
        {
            WarnInfo.RemoveAll(WarnInfoType.AlwayWarn);
        }
        #endregion

        #region 页面加载时任务
        /// <summary>
        /// 页面第一次加载时执行的任务
        /// </summary>
        public void LoadTask()
        {
            //注册警告事件
            WarnInfo.WarnInfoChanged += (all, add, rem) =>
            {
                //界面展示
                TextErr = string.Join(Environment.NewLine, all.OrderBy(o => (o.WarnType, o.Source, o.Text)));
                //日志记录
                Logs.Write(add.Concat(rem).Select(o => o.ToString()), LogsType.Warning);
                //数据库保存
                if (WarnInfoDb.IsEnabled)
                {
                    WarnInfoDb.db.Insertable(WarnInfoItemDb.GetList(add)).ExecuteCommand();
                    WarnInfoDb.db.Updateable(WarnInfoItemDb.GetList(rem)).ExecuteCommand();
                }
            };

            Task.Run(PlcErrListen);
        }

        /// <summary>
        /// 根据Excel里面的内容监听plc错误信息
        /// </summary>
        async void PlcErrListen()
        {
            //Excel解析的错误格式
            var excelErrAll = ExcelDeviceAlarmModel.GetDatas(LocalFile.PlcDotPath);
            while (true)
            {
                //需要将null替换为设备，如“LocalStatic.Plc”，并去里面解开注释
                var excelErr = ExcelDeviceAlarmModel.ReadPlcAlarm(excelErrAll, null);

                WarnInfo.AddOrUpdate(excelErr.Select(o => new WarnInfoItem()
                {
                    Text = o.名称,
                    WarnType = WarnInfoType.WhileWarn,
                    Level = o.级别,
                    Solution = o.解决方式
                }), "PLC");

                await Task.Delay(500);
            }
        }
        #endregion

        #region 业务

        private RunState runState = RunState.Stop;
        /// <summary>
        /// 运行状态
        /// </summary>
        public RunState RunState { get => runState; set { SetProperty(ref runState, value); } }

        public ICommand RunStateClickCommand { get => new DelegateCommand<RunStateButtonClick>(RunStateClick); }
        /// <summary>
        /// 运行状态
        /// </summary>
        public void RunStateClick(RunStateButtonClick clickrunState)
        {
            if (clickrunState == RunStateButtonClick.Start)
            {
                TextBoxLog.AddLog("点击开始");
                Start();
            }
            else if (clickrunState == RunStateButtonClick.Pause)
            {
                TextBoxLog.AddLog("点击暂停");
                Pause();
            }
            else if (clickrunState == RunStateButtonClick.Continue)
            {
                TextBoxLog.AddLog("点击继续");
                Continue();
            }
            else if (clickrunState == RunStateButtonClick.Stop)
            {
                TextBoxLog.AddLog("点击停止");
                Stop();
            }
            else if (clickrunState == RunStateButtonClick.Rset)
            {

            }
        }

        /// <summary>
        /// 开始
        /// </summary>
        private void Start()
        {
            cancellationToken = new CancellationTokenSource();
            manualReset = new ManualResetEvent(true);
            Task.Run(TaskAll);
            RunState = RunState.Run;
        }

        /// <summary>
        /// 暂停
        /// </summary>
        public void Pause()
        {
            manualReset.Reset();
            RunState = RunState.Pause;
        }

        /// <summary>
        /// 继续
        /// </summary>
        public void Continue()
        {
            manualReset.Set();
            RunState = RunState.Run;
        }

        /// <summary>
        /// 停止
        /// </summary>
        public void Stop()
        {
            cancellationToken.Cancel();
            RunState = RunState.Stop;
        }

        private void TaskAll()
        {

            try
            {
                Task.WaitAll(Task1(), Task2());
            }
            catch (Exception ex)
            {
                TextBoxLog.AddLog($"错误：{ex.ToString()}");
            }
            finally
            {
                Stop();
                TextBoxLog.AddLog("已停止：全部");
            }
        }

        private async Task Task1()
        {
            try
            {
                for (int i = 0; true; i++)
                {
                    await Task.Delay(500);
                    //监听：开始、暂停、停止
                    While.Wait(cancellationToken.Token, manualReset);

                    TextBoxLog.AddLog($"任务1：{i}");
                }
            }
            catch (OperationCanceledException)
            {
                TextBoxLog.AddLog("已停止1");
            }
            catch (Exception ex)
            {
                TextBoxLog.AddLog($"错误：{ex.ToString()}");
            }
            finally
            {
                cancellationToken?.Cancel();
            }
        }

        private async Task Task2()
        {
            try
            {
                for (int i = 0; true; i++)
                {
                    await Task.Delay(500);
                    //监听：开始、暂停、停止
                    While.Wait(cancellationToken.Token, manualReset);

                    TextBoxLog.AddLog($"任务2：{i}");
                }
            }
            catch (OperationCanceledException)
            {
                TextBoxLog.AddLog("已停止2");
            }
            catch (Exception ex)
            {
                TextBoxLog.AddLog($"错误：{ex.ToString()}");
            }
            finally
            {
                cancellationToken?.Cancel();
            }
        }
        #endregion
    }
}
